/*-----------------------------------------------------------------------
 *
 * c_keywords.c
 *	  在 PostgreSQL 嵌入式 SQL 中查找保留字的词法标记
 *
 * src/interfaces/ecpg/preproc/c_keywords.c
 *
 *-----------------------------------------------------------------------
 */
#include "postgres_fe.h"

/* ScanKeywordList 查找 C 关键字数据 */
#include "c_kwlist_d.h"
#include "preproc_extern.h"
#include "preproc.h"

/* C 关键字的标记代码 */
#define PG_KEYWORD(kwname, value) value,

static const uint16 ScanCKeywordTokens[] = {
#include "c_kwlist.h"
};

#undef PG_KEYWORD


/*
 * ScanCKeywordLookup - 检查给定的单词是否为关键字
 *
 * 返回关键字的标记值，如果没有匹配则返回 -1。
 *
 * 使用普通的 strcmp() 比较进行哈希搜索。这与
 * ScanKeywordLookup() 类似，只是我们需要大小写敏感的匹配。
 */
int ScanCKeywordLookup(const char *fc_str)
{
	size_t		fc_len;
	int			fc_h;
	const char *fc_kw;

	/*
	 * 如果长度过长，则立即拒绝成为任何关键字。这可以节省
	 * 对长字符串进行无用的哈希工作。
	 */
	fc_len = strlen(fc_str);
	if (fc_len > ScanCKeywords.max_kw_len)
		return -1;

	/*
	 * 计算哈希函数。由于这是一个完美的哈希，我们只需要
	 * 匹配它所标识的特定关键字。
	 */
	fc_h = ScanCKeywords_hash_func(fc_str, fc_len);

	/* 超出范围的结果表示没有匹配 */
	if (fc_h < 0 || fc_h >= ScanCKeywords.num_keywords)
		return -1;

	fc_kw = GetScanKeyword(fc_h, &ScanCKeywords);

	if (strcmp(fc_kw, fc_str) == 0)
		return ScanCKeywordTokens[fc_h];

	return -1;
}
